import functools
import logging
import os
import torch
import time
import gc
from typing import Any, Callable

# === 1. 路径工具 ===
# 获取项目的根目录
def get_project_home() -> str:
    """
    获取项目根目录（即项目主文件夹），兼容不同操作系统，使用 os.path.normpath 规范化路径。

    Returns:
        str: 项目根目录路径
    """
    # 获取当前文件的绝对路径
    current_file_path = os.path.abspath(__file__)
    # 获取当前文件所在目录
    current_dir = os.path.dirname(current_file_path)
    # 向上两级目录作为项目根目录（根据你的目录结构调整）
    # 当前文件所在目录是 monet/utils/，所以向上两级目录就是项目根目录
    project_home = os.path.normpath(os.path.join(current_dir, ".."))
    return project_home


def get_path(rel_path):
    return os.path.join(get_project_home(), rel_path)


# === 2. 日志配置函数（只应调用一次）===
def setup_logger() -> logging.Logger:
    """
    配置并返回一个全局 logger 实例。
    包含控制台输出和文件输出（logs/app.log）。
    """
    # 确保日志目录存在
    log_dir = get_path("logs")
    os.makedirs(log_dir, exist_ok=True)

    # 日志文件路径
    log_file = os.path.join(log_dir, "app.log")

    # 创建 logger（使用模块名，便于追踪来源）
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    # 避免重复添加 handler（重要！）
    if logger.hasHandlers():
        logger.handlers.clear()

    # 创建格式器
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )

    # 控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_handler.setFormatter(formatter)

    # 文件处理器
    file_handler = logging.FileHandler(log_file, encoding="utf-8", mode="a")
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)

    # 添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)

    return logger


logger = setup_logger()


def timer(func: Callable) -> Callable:
    @functools.wraps(func)
    def wrapper_timer(*args: Any, **kwargs: Any) -> Any:
        start_time = time.perf_counter()
        try:
            result = func(*args, **kwargs)
        finally:
            end_time = time.perf_counter()
            run_time = end_time - start_time

        # 性能等级，方便进行耗时等级统计
        if run_time > 3.0:
            cost = "HIGH"
        elif run_time > 1.0:
            cost = "MEDIUM"
        else:
            cost = "LOW"

        # 特定函数附加信息
        additional = ""
        if func.__name__ == "pack_message":
            response = kwargs.get("response", "")
            if response:
                additional = f"[response={response}]"

        # 构建日志消息
        msg = (
            f"===> timer:[{cost}] # "
            f"[{func.__module__}] # "
            f"[{func.__name__}] # "
            f"{additional} # "
            f"{run_time:.4f} secs <==="
        )
        logger.info(msg)

        return result

    return wrapper_timer

def torch_gc():
    gc.collect()
    if torch.cuda.is_available():
        torch.cuda.empty_cache()
        torch.cuda.ipc_collect()

if __name__ == "__main__":
    print(get_project_home())
    print(get_path("logs"))
